package com.example.rjb_shoping.service.impl;

import com.example.rjb_shoping.config.RjbConstant;
import com.example.rjb_shoping.entity.RjbSpkie;
import com.example.rjb_shoping.dao.RjbSpkieDao;
import com.example.rjb_shoping.query.SpkieQuery;
import com.example.rjb_shoping.service.RjbSpkieService;
import com.example.rjb_shoping.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * (RjbSpkie)表服务实现类
 *
 * @author makejava
 * @since 2021-06-09 20:43:27
 */
@Slf4j
@Service("rjbSpkieService")
public class RjbSpkieServiceImpl implements RjbSpkieService {
    @Resource
    private RjbSpkieDao rjbSpkieDao;

    @Autowired
    RedisUtils redisUtils;
    /**
     * 通过ID查询单条数据
     *
     * @param sId 主键
     * @return 实例对象
     */
    @Override
    public RjbSpkie queryById(Integer sId) {
        return this.rjbSpkieDao.queryById(sId);
    }
    @Scheduled(cron = "0 0 */1 * * ?") //每1小时执行1次
    @PostConstruct
    public void preLoadTodaySeckill() {
        SpkieQuery query = new SpkieQuery();
        //获取当天的日期
        String now = DateFormatUtils.format(Calendar.getInstance().getTime(), "yyyy-MM-dd");
        query.setStartDate(now);
        query.setEndDate(now);
        //查询今日的秒杀商品列表
        List<RjbSpkie> rjbSpkies = queryAllByLimit(query);
        //将今日秒杀活动载入redis
        redisUtils.set(RjbConstant.TODAY_SECKILL_KEY, rjbSpkies, 1, TimeUnit.DAYS);
        log.info("将今日秒杀活动载入redis");
        for (RjbSpkie spkie : rjbSpkies) {
            Integer stock = spkie.getSLimit(); //获取当前秒杀商品的库存数量
            //重置该秒杀商品的库存
            redisUtils.del(RjbConstant.TODAY_SECKILL_STOCK+spkie.getSId()+":"+ spkie.getMId());
            //重置该秒杀商品订单的计数器
            redisUtils.del(RjbConstant.ORDER_FOR_SECKILL_COUNTER + ":" + spkie.getSId());
            //重置秒杀商品订单状态
            redisUtils.del(RjbConstant.ORDER_FOR_SECKILL + "*");
            List<Object> sIds = new ArrayList<>(stock);
            for (int i = 0; i < stock; i++) {
                sIds.add(spkie.getSId()); //添加秒杀Id
            }
            if (sIds.size() > 0) {
                //秒杀商品库存量，有效期24小时-1分钟
                redisUtils.llSet(RjbConstant.TODAY_SECKILL_STOCK + spkie.getSId() + ":" + spkie.getMId(), sIds, 60*60*24-60);
                log.info("已将秒杀商品{}的库存添加到redis中", spkie.getSId());
            }
        }
    }

    /**
     * 获取今天的秒杀商品列表
     * @return
     */
    public List<RjbSpkie> getTodaySeckills() {
        List<RjbSpkie> rjbSpkies = (List<RjbSpkie>) redisUtils.get(RjbConstant.TODAY_SECKILL_KEY);
        return rjbSpkies;
    }

    @Override
    public List<RjbSpkie> queryAllByLimit(SpkieQuery query) {
        List<RjbSpkie> rjbSpkies = this.rjbSpkieDao.queryAllByLimit(query);
        return rjbSpkies;
    }

    @Override
    public RjbSpkie insert(RjbSpkie rjbSpkie) {
        int row = this.rjbSpkieDao.insert(rjbSpkie);

        if (row > 0) {
            //获取当前秒杀商品的库存数量
            Integer stock = rjbSpkie.getSLimit();
            List<Object> sIds = new ArrayList<>(stock);
            for (int i = 0; i < stock; i++) {
                sIds.add(rjbSpkie.getSId()); //添加秒杀Id
            }
            redisUtils.llSet(RjbConstant.TODAY_SECKILL_STOCK+rjbSpkie.getSId()+":"+ rjbSpkie.getMId(), sIds, 60*60*24-60);
            return rjbSpkie;
        }
        return null;
    }

    @Override
    public RjbSpkie update(RjbSpkie rjbSpkie) {
        int i = this.rjbSpkieDao.update(rjbSpkie);
        if(i > 0)return this.queryById(rjbSpkie.getSId());
        return null;
    }

    @Override
    public boolean deleteById(Integer sId) {
        return this.rjbSpkieDao.deleteById(sId) > 0;
    }

    @Override
    public List<RjbSpkie> queryByList(){
        return this.rjbSpkieDao.queryByList();
    }


}
